package vcp.client.GUI.mvc.controller;

import javax.swing.SwingUtilities;

import vcp.client.GUI.events.ComplaintUpdateEvent;
import vcp.client.GUI.mvc.model.UIAbstractModel;
import vcp.client.GUI.mvc.model.UICompHandleModel;
import vcp.client.GUI.mvc.view.UIAbstractView;
import vcp.client.GUI.mvc.view.UICompHandleView;
import vcp.client.interfaces.listeners.IComplaintUpdateListener;
import vcp.client.utility.Common.UserNotification;
import vcp.entity.Complaint;
import vcp.entity.Worker;
import vcp.enums.ComplaintType.ComplaintStatus;
import vcp.enums.PopUpMessageType;
import vcp.enums.Screen;

/**
 * 
 * @author VCP team
 *         <p>
 *         complaint handler controller
 *         </p>
 * 
 * @see UICompHandleView
 * @see UICompHandleModel
 * @see IComplaintUpdateListener
 */
public class UICompHandleController extends UIAbstractController implements IComplaintUpdateListener
{
	/** reference to view **/
	private final UICompHandleView view;
	/** reference to mode; **/
	private final UICompHandleModel model;

	/**
	 * 
	 * @param view
	 *            new screen set
	 * @param model
	 *            info to the new screen
	 */
	public UICompHandleController ( UICompHandleView view, UICompHandleModel model )
	{
		super(Screen.COMPLAINT_HANDLE);
		this.view = view;
		this.model = model;
		this.setupListeners();
	}

	// ****************************************************************************************************************************
	// Private methods
	// ****************************************************************************************************************************
	/**
	 * <p>
	 * Prepare the complaint to reload on screen
	 * </p>
	 * 
	 * @param complaint
	 */
	private synchronized void prepareForReload ( final Complaint complaint )
	{
		this.view.setOnScreen(false);
		if ( this.isComplaintEqualToCurrentComplaint(complaint) )
		{
			this.reloadGUI(complaint);
		}
		else if ( this.hasNewComplaintJustAdded() )
		{
			this.view.addNewComplaintID(complaint.getID());
			this.reloadGUI(complaint);
		}
		else
		{
			this.view.addNewComplaintID(complaint.getID());
		}
		this.view.setOnScreen(true);
	}

	/**
	 * reload the GUI with complaint update info to screen
	 * 
	 * @param complaint
	 */
	private void reloadGUI ( Complaint complaint )
	{
		this.view.loadComplaintInfo(complaint);
	}

	/**
	 * verifies if new complaint just added
	 * 
	 * @return true if new complaint added
	 */
	private boolean hasNewComplaintJustAdded ()
	{
		return this.model.getCustomersComplaints().size() == 1;
	}

	/**
	 * check if complaint equal to current complain
	 * 
	 * @param complaint
	 * @return true if given complaint equal to the one on screen
	 */
	private boolean isComplaintEqualToCurrentComplaint ( Complaint complaint )
	{
		return complaint.getID().intValue() == this.view.getCurrentComplaintID().intValue();
	}

	// ****************************************************************************************************************************
	// UIAbstractController methods
	// ****************************************************************************************************************************
	@Override
	public UIAbstractView getView ()
	{
		return this.view;
	}

	@Override
	public UIAbstractModel getModel ()
	{
		return this.model;
	}

	@Override
	public void clearMVC ()
	{
		this.view.setOnScreen(false);
	}

	@Override
	public void flashData ()
	{
		this.view.clearView();
		this.model.clearModel();
	}

	@Override
	public void uploadDataContext ( Object data )
	{
		if ( data instanceof Worker )
		{
			this.flashData();
			Worker worker = (Worker) data;

			this.model.setCustomerServiceWorker(worker);
			if ( this.model.hasComplaints() )
			{
				this.view.loadAllComplaintIDs(this.model.getCustomersComplaints());
				this.reloadGUI(this.model.getFirstCustomerComplaint());
			}

			this.model.shouldRegisterForUpdates();
			this.view.setOnScreen(true);
		}
	}

	@Override
	protected void setupListeners ()
	{
		super.setupListeners();
		this.view.setComplaintUpdateListener(this);
	}

	// ****************************************************************************************************************************
	// IControllerViewDelegate methods
	// ****************************************************************************************************************************
	@Override
	public void onButtonPress ( Object object )
	{
		if ( object instanceof Integer )
		{
			Integer selected = (Integer) object;
			this.reloadGUI(this.model.getCustomerComplaintByID(selected));
		}
	}

	// ****************************************************************************************************************************
	// IControllerModelDelegate methods
	// ****************************************************************************************************************************
	@Override
	public void updateControllerDelegateWithData ( Object newData )
	{
		this.parentDelegate.notifyOnDataUpdate(this.model.getCustomerServiceWorker());
		if ( this.view.isOnScreen() )
		{
			if ( newData instanceof Complaint )
			{
				if ( this.hasNewComplaintJustAdded() )
				{
					this.parentDelegate.showPopUpMessage(String.format(UserNotification.__VALUE__IS_UPDATED, "Complaints info"), PopUpMessageType.INFORMATION);
				}

				final Complaint complaint = (Complaint) newData;
				SwingUtilities.invokeLater(new Runnable()
					{
						@Override
						public void run ()
						{
							UICompHandleController.this.prepareForReload(complaint);
						}
					});
			}
			else if ( newData instanceof String )
			{
				String notification = (String) newData;
				this.parentDelegate.showPopUpMessage(notification, PopUpMessageType.INFORMATION);
			}
		}
	}

	// ****************************************************************************************************************************
	// IComplaintUpdatable methods
	// ****************************************************************************************************************************
	@Override
	public void onComplaintUpdate ( ComplaintUpdateEvent updateEvent )
	{
		Complaint currentComplaint = this.model.getCustomerComplaintByID(this.view.getCurrentComplaintID());

		Complaint newComplaint = new Complaint();

		// copies data into new complaint
		newComplaint.setID(this.view.getCurrentComplaintID());
		newComplaint.setCustomerID(currentComplaint.getCustomerID());
		newComplaint.setType(currentComplaint.getType());
		newComplaint.setText(currentComplaint.getText());
		newComplaint.setStatus(updateEvent.getNewStatus());
		newComplaint.setOpenDate(currentComplaint.getOpenDate());
		newComplaint.setResolveText(updateEvent.getResolveText());
		newComplaint.setCustomerOfComplaint(currentComplaint.getCustomerOfComplaint());
		newComplaint.setComplaintResolve(updateEvent.getResolve());
		newComplaint.setAmountRefound(updateEvent.getRefundAmount());
		newComplaint.setHistory(newComplaint.getStatus() == ComplaintStatus.CLOSED);
		newComplaint.setSiteEnum(currentComplaint.getSiteEnum());

		this.model.saveComplaint(newComplaint);
	}

}
